package org.jeecgframework.web.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecgframework.core.common.model.json.AjaxJson;
import org.jeecgframework.core.common.service.impl.CommonServiceImpl;
import org.jeecgframework.core.util.DataUtils;
import org.jeecgframework.core.util.DateUtils;
import org.jeecgframework.core.util.StringUtil;
import org.jeecgframework.web.service.UploadEquipmentService;
import org.jeecgframework.web.system.pojo.base.TSDepart;
import org.jeecgframework.web.system.pojo.base.ZyEquipmentSpareEntity;
import org.jeecgframework.web.system.pojo.base.ZyUpEquipmentThread;
import org.jeecgframework.web.system.service.SystemService;
import org.jeecgframework.web.util.ExcelImportUtil;
import org.jeecgframework.web.util.ExcelUtil;
import org.jeecgframework.web.util.FileBean;
import org.jeecgframework.web.util.StaticValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author ZhangYunlong
 * @version V1.0
 * @Title: UploadEquipmentServiceImpl
 * @Description: 上传设备信息
 * @date 2016-04-01
 */
@Service("uploadEquipmentService")
@Transactional(rollbackFor = Exception.class)
public class UploadEquipmentServiceImpl extends CommonServiceImpl implements UploadEquipmentService {

    public final static String servering = "服务中";
    public final static String notUsed = "未使用";
    public final static String stop = "暂停服务";

    @Autowired
    private SystemService systemService;

    /**
     * @param request
     * @param aj
     * @return AjaxJson
     * @throws Exception
     * @Title：checkExcel
     * @Description：验证SN是否为空并且修改数据
     * @author：LeiYoung
     * @Date：2016年10月13日 上午10:18:52
     */
    public AjaxJson doCheckAndUpdateExcelByRenewal(FileBean fileBean, AjaxJson aj) throws Exception {

        if (fileBean == null) {
            // 文件为空
            aj.setSuccess(false);
            aj.setMsg("上传文件错误，请修改后再导入！");
            return aj;
        }

        // 解析Excel数据
        List<Map<String, Object>> dataList = ExcelImportUtil.importExcel(fileBean, 0);

        // 定义修改的实体类集合
        List<ZyEquipmentSpareEntity> updateList = new ArrayList<ZyEquipmentSpareEntity>();// 实例化集合

        // 数据不能为空并且数据行数大于1
        if (dataList != null && dataList.size() > 1) {

            // SN
            String sn = !StringUtil.isNotEmpty(dataList.get(0).get("0")) ? "" : dataList.get(0).get("0").toString();
            boolean boolSN = StringUtil.isNotEmpty(sn) && sn.indexOf("SN") != -1;

            // 保修开始日期
            String repairEndDate = !StringUtil.isNotEmpty(dataList.get(0).get("1")) ? "" : dataList.get(0).get("1").toString();
            boolean boolRepairEndDate = StringUtil.isNotEmpty(repairEndDate) && repairEndDate.indexOf("日期") != -1;

            // 剩余巡检次数
            String residualIpCount = !StringUtil.isNotEmpty(dataList.get(0).get("2")) ? "" : dataList.get(0).get("2").toString();
            boolean boolResidualIpCount = StringUtil.isNotEmpty(residualIpCount) && residualIpCount.indexOf("巡检") != -1;

            // 中影续保
            String sendSign = !StringUtil.isNotEmpty(dataList.get(0).get("3")) ? "" : dataList.get(0).get("3").toString();
            boolean boolSendSign = StringUtil.isNotEmpty(sendSign) && sendSign.indexOf("续保") != -1;

            if (!boolSN || !boolRepairEndDate || !boolResidualIpCount || !boolSendSign) {

                aj.setSuccess(false);
                aj.setMsg("Excel列标题不正确，请修改，正确的列标题{'设备SN','保修开始日期','剩余巡检次数','中影续报'}");
                return aj;

            }

            // 设备Map
            Map<String, ZyEquipmentSpareEntity> zeseMap = new HashMap<String, ZyEquipmentSpareEntity>();

            // 机构Map
            Map<String, TSDepart> tsdMap = new HashMap<String, TSDepart>();

            // 查询全部 是否是备件等于false 的设备
            List<ZyEquipmentSpareEntity> zeseList = super.findByProperty(ZyEquipmentSpareEntity.class, "isSpare", false);// 所有现有设备

            // 查询全部部门机构
            List<TSDepart> tsdList = super.findByQueryString("from TSDepart where orgType = '" + StaticValue.DIC_ORG_TYPE_THIRD_PARTY + "'");

            if (zeseList != null && zeseList.size() > 0) {
                // 遍历数据

                // 遍历设备
                for (ZyEquipmentSpareEntity zese : zeseList) {
                    zeseMap.put(zese.getSn(), zese);
                }

                // 遍历组织机构
                for (TSDepart tsd : tsdList) {
                    tsdMap.put(tsd.getBpCode(), tsd);
                }

                for (int i = 1; i < dataList.size(); i++) {

                    Map<String, Object> esMap = dataList.get(i);

                    // SN
                    sn = !StringUtil.isNotEmpty(esMap.get("0")) ? "" : esMap.get("0").toString();
                    // 保修开始日期
                    repairEndDate = !StringUtil.isNotEmpty(esMap.get("1")) ? "" : esMap.get("1").toString();
                    // 剩余巡检次数
                    residualIpCount = !StringUtil.isNotEmpty(esMap.get("2")) ? "" : esMap.get("2").toString();
                    // 中影续保
                    sendSign = !StringUtil.isNotEmpty(esMap.get("3")) ? "" : esMap.get("3").toString();

                    if (StringUtil.isEmpty(sn) && StringUtil.isEmpty(repairEndDate) && StringUtil.isEmpty(residualIpCount) && StringUtil.isEmpty(sendSign)) {
                        // 四项都为空
                        continue;
                    }
                    if (StringUtil.isNotEmpty(residualIpCount)) {
                        // 剩余巡检次数不为空
                        try {
                            Integer.parseInt(residualIpCount);
                        } catch (NumberFormatException e) {
                            aj.setSuccess(false);
                            aj.setMsg("第[" + (i + 1) + "]行剩余巡检次数不是数字类型，请修改后再导入！");
                            return aj;
                        }
                    }
                    if (StringUtil.isNotEmpty(sendSign)) {
                        // 中影续保不为空
                        try {
                            Integer.parseInt(sendSign);
                        } catch (NumberFormatException e) {
                            aj.setSuccess(false);
                            aj.setMsg("第[" + (i + 1) + "]行中影续保不是数字类型，请修改后再导入！");
                            return aj;
                        }
                    }
                    if (StringUtil.isEmpty(sn)) {
                        // SN 为空
                        aj.setSuccess(false);
                        aj.setMsg("第[" + (i + 1) + "]行SN为空，请修改后再导入！");
                        return aj;
                    }
                    boolean hadUpdate = false;// 是否存在更新情况
                    ZyEquipmentSpareEntity zese = zeseMap.get(esMap.get("0"));
                    if (zese != null) {
                        hadUpdate = false;// 是否存在更新情况
                        if (StringUtil.isNotEmpty(repairEndDate)) {
                            // 更新保修开始日期
                            zese.setWarrantyBeginDate(DataUtils.str2Date(repairEndDate.replace("/", "-"), DateUtils.date_sdf));
                            hadUpdate = true;
                        }
                        if (StringUtil.isNotEmpty(residualIpCount)) {
                            // 剩余巡检次数
                            zese.setResidualIpCount(Integer.parseInt(residualIpCount));
                            hadUpdate = true;
                        }
                        if (StringUtil.isNotEmpty(sendSign)) {
                            // 派单要求
                            if (StringUtil.isNotEmpty(tsdMap.get(sendSign))) {
                                // BP 在组织机构中能查到
                                zese.setSendSign(tsdMap.get(sendSign));
                                hadUpdate = true;
                            }
                        }
                        if (hadUpdate) {
                            updateList.add(zese);
                        }
                    }

                    if (!hadUpdate) {
                        aj.setSuccess(false);
                        aj.setMsg("第[" + (i + 1) + "]行SN在设备中查不到，请检查后再导入！");
                        return aj;
                    }
                }
            } else {
                aj.setMsg("现有设备数据为空");
                aj.setSuccess(false);
                return aj;
            }
            if (aj.isSuccess()) {
                commonDao.batchUpdate(updateList);
            }
        }
        try {
            systemService.doSaveZyFileLog(fileBean, StaticValue.IMPORT_FILE_EQUIPMENT_SPARE_RENEWAL_DATA, DataUtils.getYear() + "", StaticValue.DIC_FILE_TYPE_XLSX, StaticValue.DIC_TRUE_OR_FALSE_NUM_1);

        } catch (Exception e) {
            e.printStackTrace();
        }
        aj.setSuccess(true);
        aj.setMsg("更改续保成功！");
        return aj;

    }

    /**
     * @param HttpServletRequest 通过前台请求获得文件流
     * @Description 解析EXCEL
     */
    // public List<String> parseExcel(HttpServletRequest req,AjaxJson j) {
    // List<String> snList = new ArrayList<String>();
    // MultipartHttpServletRequest multipartRequest =
    // (MultipartHttpServletRequest) req;
    // Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
    // ZyFileLogEntity fileLog = new ZyFileLogEntity();
    // String fileName = UUID.randomUUID().toString().replace("-", "")+".xlsx";
    // XSSFWorkbook hwk = null;
    // try {
    // for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
    // MultipartFile file = entity.getValue();// 获取上传文件对象
    // hwk = ExcelUtil.analyzeExcel2(file.getInputStream());
    //
    // fileLog = new ZyFileLogEntity();
    // fileLog.setBusinessType(StaticValue.IMPORT_FILE_EQUIPMENT_SPARE_BASE_DATA);
    // //文件业务
    // fileLog.setOldFileName(file.getOriginalFilename());//文件原名
    // fileLog.setNewFileName(fileName);//文件新名
    // fileLog.setFilePath(StaticValue.UPLAOD_FILE_PATH+fileName);
    // fileLog.setFileType("xlsx");
    // fileLog.setStatus("0");
    // super.save(fileLog);
    //
    // ExcelWrite.createExcel(hwk,fileName);
    // j.setObj(fileLog.getFilePath());
    // snList = getSnFromExcel(hwk);
    // }
    // } catch (IOException e) {
    // e.printStackTrace();
    // } catch (Exception e) {
    // e.printStackTrace();
    // }
    // return snList;
    // }
    public List<Map<String, String>> parseExcel(HttpServletRequest req, AjaxJson j) {
        String filePath = req.getParameter("filePath");
        List<Map<String, String>> snMapList = new ArrayList<Map<String, String>>();
        j.setObj(filePath);
        XSSFWorkbook hwk;
        try {
            hwk = new XSSFWorkbook(new FileInputStream(new File(filePath)));
            snMapList = getSnFromExcel(hwk);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return snMapList;
    }

    /**
     * @return sn List
     * @author xiul 2016-6-7 下午4:40:07 Description 单取出 sn
     */
    private List<Map<String, String>> getSnFromExcel(XSSFWorkbook xssfWb) {
        List<Map<String, String>> snMapList = new ArrayList<Map<String, String>>();
        XSSFSheet sheet = xssfWb.getSheetAt(0);// 默认只取第一个sheet页
        try {
            int maxUnit = 1000;
            int snColumNum = 0;
            int itemColunNum = 1;
            int countRow = sheet.getPhysicalNumberOfRows();
            int threadC = countRow / maxUnit;
            int points = countRow % maxUnit;
            if (threadC > 0) {
                if (points > 0) {
                    threadC = threadC + 1;
                }
            } else {
                threadC = 1;
            }
            for (int r = 1; r < countRow; r++) {
                Map<String, String> map = new HashMap<String, String>();
                map.put("sn", ExcelUtil.getCellValue(sheet.getRow(r).getCell(snColumNum)));
                map.put("item", ExcelUtil.getCellValue(sheet.getRow(r).getCell(itemColunNum)));
                snMapList.add(map);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return snMapList;
    }

    @Override
    public Map<String, String> checkSnRepeat(List<Map<String, String>> snMapList, int begin, int end) {
        System.out.println("beginR:" + begin);
        System.out.println("endR:" + end);
        for (int i = begin; i <= end; i++) {
            for (int c = i + 1; c < snMapList.size(); c++) {
                if (snMapList.get(i).get("sn").equals(snMapList.get(c).get("sn")) && !snMapList.get(i).get("item").equals(snMapList.get(i).get("item"))) {
                    return snMapList.get(i);
                }
            }
        }
        return null;
    }

	/*
     * @Override public void readExcel(String filePath) { List<Map<String,
	 * Object>> mapList = ExcelUtil.analyzeExcel(filePath, "1");
	 * List<ZyEquipmentSpareEntity> esList = new
	 * ArrayList<ZyEquipmentSpareEntity>();
	 * 
	 * List<ZyEquipmentTypeEntity> esTypes =
	 * super.getList(ZyEquipmentTypeEntity.class); List<ZyCinemaEntity> cms =
	 * super.getList(ZyCinemaEntity.class); List<ZyRoomEntity> rms =
	 * super.getList(ZyRoomEntity.class);
	 * 
	 * ZyEquipmentSpareEntity zyEquipmentSpareEntity = null;
	 * ZyEquipmentTypeEntity zyEquipmentTypeEntity = null; ZyRoomEntity zyRoom =
	 * null; ZyCinemaEntity zyCinema = null; System.out.println("开始解析");
	 * SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd"); for (int i = 1;
	 * i < mapList.size(); i++) { Map<String, Object> map = mapList.get(i);
	 * 
	 * String serverState = ""; zyEquipmentSpareEntity = new
	 * ZyEquipmentSpareEntity();
	 * zyEquipmentSpareEntity.setSn(StringUtil.getString(map.get("0")));
	 * zyEquipmentSpareEntity.setItem(StringUtil.getString(map.get("1")));
	 * zyEquipmentSpareEntity.setTopItemSn(StringUtil.getString(map.get("2")));
	 * String cinemaName = StringUtil.getString(map.get("4")); zyCinema = null;
	 * for (ZyCinemaEntity cm : cms) { if(cm.getName().equals(cinemaName)){
	 * zyCinema = cm; break; } } if(StringUtil.isNotEmpty(zyCinema)){
	 * zyEquipmentSpareEntity.setZyCinema(zyCinema);
	 * zyEquipmentSpareEntity.setTsTerritory(zyCinema.getProvince()); }else{
	 * zyEquipmentSpareEntity.setZyCinema(null);
	 * zyEquipmentSpareEntity.setTsTerritory(null); } zyRoom = null; for
	 * (ZyRoomEntity rm : rms) { if(null != rm.getRoomCinema() &&
	 * rm.getRoomCinema().getName().equals(cinemaName) &&
	 * rm.getRoomNum().equals(StringUtil.getString(map.get("5")))){ zyRoom = rm;
	 * break; } } zyEquipmentSpareEntity.setHouse(zyRoom);
	 * zyEquipmentSpareEntity
	 * .setInstallDate(DateUtils.str2Date(StringUtil.getString(map.get("6")),
	 * sf));
	 * 
	 * zyEquipmentSpareEntity.setBaseRepairDate(DateUtils.str2Date(StringUtil.
	 * getString(map.get("7")), sf));
	 * 
	 * zyEquipmentSpareEntity.setSendDate(DateUtils.str2Date(StringUtil.getString
	 * (map.get("8")), sf));
	 * 
	 * zyEquipmentSpareEntity.setRepairEndDate(DateUtils.str2Date(StringUtil.
	 * getString(map.get("9")), sf));
	 * 
	 * // String dateCellVal = ExcelUtil.getCellValue(row.getCell(6)); //
	 * dateCellVal = DateUtils.judgeDateStr("-",dateCellVal) ? dateCellVal : "";
	 * //
	 * zyEquipmentSpareEntity.setInstallDate(dateCellVal.equals("")?null:ft.parse
	 * (dateCellVal));
	 * 
	 * // dateCellVal = ExcelUtil.getCellValue(row.getCell(7)); // dateCellVal =
	 * DateUtils.judgeDateStr("-",dateCellVal) ? dateCellVal : ""; //
	 * zyEquipmentSpareEntity
	 * .setBaseRepairDate(dateCellVal.equals("")?null:ft.parse(dateCellVal)); //
	 * // dateCellVal = ExcelUtil.getCellValue(row.getCell(8)); // dateCellVal =
	 * DateUtils.judgeDateStr("-",dateCellVal) ? dateCellVal : ""; //
	 * zyEquipmentSpareEntity
	 * .setSendDate(dateCellVal.equals("")?null:ft.parse(dateCellVal)); // //
	 * dateCellVal = ExcelUtil.getCellValue(row.getCell(9)); // dateCellVal =
	 * DateUtils.judgeDateStr("-",dateCellVal) ? dateCellVal : ""; //
	 * zyEquipmentSpareEntity
	 * .setRepairEndDate(dateCellVal.equals("")?null:ft.parse(dateCellVal));
	 * 
	 * serverState = StringUtil.getString(map.get("10")); switch(serverState){
	 * case servering : serverState = StaticValue.DIC_SERVER_STATE_1001; break;
	 * case notUsed : serverState = StaticValue.DIC_SERVER_STATE_1002; break;
	 * case stop : serverState = StaticValue.DIC_SERVER_STATE_1003; break;
	 * default: serverState = ""; }
	 * zyEquipmentSpareEntity.setServerState(serverState);
	 * zyEquipmentSpareEntity.setRemarks(StringUtil.getString(map.get("11")));
	 * zyEquipmentSpareEntity
	 * .setIsNormal(StringUtil.getString(map.get("12")).equals("TRUE")?"1":"0");
	 * zyEquipmentSpareEntity
	 * .setExceptionReason(StringUtil.getString(map.get("13")));
	 * zyEquipmentSpareEntity.setBpNo(StringUtil.getString(map.get("14"))); for
	 * (ZyEquipmentTypeEntity es : esTypes) {
	 * if(es.getTypeDesc().equals(StringUtil.getString(map.get("15")))){
	 * zyEquipmentTypeEntity = es; break; } }
	 * zyEquipmentSpareEntity.setType(zyEquipmentTypeEntity);
	 * zyEquipmentSpareEntity
	 * .setIsServicing(StringUtil.getString(map.get("16")).
	 * equals("TRUE")?"1":"0"); if((null !=
	 * zyEquipmentSpareEntity.getTopItemSn() &&
	 * !zyEquipmentSpareEntity.getTopItemSn().equals("")) &&
	 * !zyEquipmentSpareEntity
	 * .getSn().equals(zyEquipmentSpareEntity.getTopItemSn())){
	 * zyEquipmentSpareEntity.setIsSpare(true); }else{
	 * zyEquipmentSpareEntity.setIsSpare(false); }
	 * esList.add(zyEquipmentSpareEntity); } System.out.println("开始保存");
	 * super.batchSave(esList); System.out.println("保存完毕"); }
	 */

    @Override
    public void readExcel(String filePath) {
        File excelFile = new File(filePath);
        FileInputStream is;
        try {
            is = new FileInputStream(excelFile);
            XSSFWorkbook xssfWb = new XSSFWorkbook(is);
            XSSFSheet sheet = xssfWb.getSheetAt(0);
            int maxUnit = 3000;// 每N 条 启动一个线程
            int countRow = sheet.getPhysicalNumberOfRows();
            int threadC = countRow / maxUnit;
            int points = countRow % maxUnit;
            if (threadC > 0) {
                if (points > 0) {
                    threadC = threadC + 1;
                }
            } else {
                threadC = 1;
            }
            System.out.println("启动线程数量:" + threadC);
            for (int i = 0; i < threadC; i++) {
                int beginR = i == 0 ? 1 : i * maxUnit + 1;
                int endR = i == (threadC - 1) ? countRow : beginR + maxUnit - 1;
                ZyUpEquipmentThread upEuqipmentThread = new ZyUpEquipmentThread(beginR, endR, sheet);
                upEuqipmentThread.start();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
